<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者，助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件，未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------


namespace app;

use crmeb\traits\Macro;
use think\File;
use think\file\UploadedFile;

class Request extends \think\Request
{
    use Macro;

    protected $cache = [];

    /**
     * 不过滤变量名
     * @var array
     */
    protected  $except = [
        'menu_path', 'api_url', 'unique_auth',
        'description', 'custom_form', 'product_detail_diy', 'member', 'product_category_diy'
    ];

    public function __construct()
    {
        parent::__construct();
        $this->filter[] = function ($val) {
            return is_string($val) ? trim($val) : $val;
        };
    }

    public function ip(): string
    {
        return $this->header('remote-host') ?? parent::ip();
    }

    public function isApp()
    {
        return $this->header('Form-type') === 'app';
    }


    public function isWechat()
    {
        return $this->header('Form-type') === 'wechat';
    }

    /**
     * @param $db
     * @param $key
     * @return bool
     * @author xaboy
     * @day 2020/10/22
     */
    public function hasCache($db, $key)
    {
        return isset($this->cache[$db][$key]);
    }

    /**
     * @param $db
     * @param $key
     * @return array|mixed|string
     * @author xaboy
     * @day 2020/10/22
     */
    public function getCache($db, $key)
    {
        if (is_array($key)) {
            $data = [];
            foreach ($key as $v) {
                $data[$v] = $this->getCache($db, $v);
            }
            return $data;
        }
        return $this->cache[$db][$key] ?? '';
    }

    /**
     * @param $db
     * @param $key
     * @param null $value
     * @author xaboy
     * @day 2020/10/22
     */
    public function setCache($db, $key, $value = null)
    {
        if (!isset($this->cache[$db])) $this->cache[$db] = [];
        if (is_array($key)) {
            foreach ($key as $k => $v) {
                $this->setCache($db, $k, $v);
            }
            return;
        }
        $this->cache[$db][$key] = $value;
    }

    public function clearCache()
    {
        $this->cache = [];
    }

    public function params(array $names, $filter = '')
    {
        $data = [];
        $flag = false;
        if ($filter === true) {
            $filter = '';
            $flag = true;
        }
        foreach ($names as $name) {
            if (!is_array($name))
                $data[$name] = $this->param($name, '', $filter);
            else
                $data[$name[0]] = $this->param($name[0], $name[1], $filter);
        }

        return $flag ? array_values($data) : $data;
    }
    /**
     * 获取请求的数据
     * @param array $params
     * @param bool $suffix
     * @param bool $filter
     * @return array
     */
    public function more(array $params, bool $suffix = false, bool $filter = true): array
    {
        $p = [];
        $i = 0;
        foreach ($params as $param) {
            if (!is_array($param)) {
                $p[$suffix == true ? $i++ : $param] = $this->filterWord(is_string($this->param($param)) ? trim($this->param($param)) : $this->param($param), $filter && !in_array($param, $this->except));
            } else {
                if (!isset($param[1])) $param[1] = null;
                if (!isset($param[2])) $param[2] = '';
                if (is_array($param[0])) {
                    $name = is_array($param[1]) ? $param[0][0] . '/a' : $param[0][0] . '/' . $param[0][1];
                    $keyName = $param[0][0];
                } else {
                    $name = is_array($param[1]) ? $param[0] . '/a' : $param[0];
                    $keyName = $param[0];
                }
                $p[$suffix == true ? $i++ : ($param[3] ?? $keyName)] = $this->filterWord(is_string($this->param($name, $param[1], $param[2])) ? trim($this->param($name, $param[1], $param[2])) : $this->param($name, $param[1], $param[2]), $filter && !in_array($keyName, $this->except));
            }
        }
        return $p;
    }


    /**
     * 过滤接受的参数
     * @param $str
     * @param bool $filter
     * @return array|mixed|string|string[]
     */
    public function filterWord($str, bool $filter = true)
    {
        if (!$str || !$filter) return $str;
        // 把数据过滤
        $farr = [
            "/<(\\/?)(script|i?frame|style|html|body|title|link|meta|object|\\?|\\%)([^>]*?)>/isU",
            "/(<[^>]*)on[a-zA-Z]+\s*=([^>]*>)/isU",
            "/select|join|where|drop|like|modify|rename|insert|update|table|database|alter|truncate|\'|\/\*|\.\.\/|\.\/|union|into|load_file|outfile/is"
        ];
        if (is_array($str)) {
            foreach ($str as &$v) {
                if (is_array($v)) {
                    foreach ($v as &$vv) {
                        if (!is_array($vv)) $vv = preg_replace($farr, '', $vv);
                    }
                } else {
                    $v = preg_replace($farr, '', $v);
                }
            }
        } else {
            $str = preg_replace($farr, '', $str);
        }
        return $str;
    }

    public function merId()
    {
        return intval($this->hasMacro('merchantId') ? $this->merchantId() : 0);
    }

    public function merAdminId()
    {
        return intval($this->hasMacro('adminId') ? $this->adminId() : 0);
    }

    public function setOriginFile($name, $array)
    {
        $this->file[$name] = $array;
    }

    public function getOriginFile($name)
    {
        return $this->file[$name] ?? null;
    }


    protected function dealUploadFile(array $files, string $name): array
    {
        $array = [];
        foreach ($files as $key => $file) {
            if (is_array($file['name'])) {
                $item = [];
                $keys = array_keys($file);
                $count = count($file['name']);

                for ($i = 0; $i < $count; $i++) {
                    if ($file['error'][$i] > 0) {
                        if ($name == $key) {
                            $this->throwUploadFileError($file['error'][$i]);
                        } else {
                            continue;
                        }
                    }

                    $temp['key'] = $key;

                    foreach ($keys as $_key) {
                        $temp[$_key] = $file[$_key][$i];

                        $name = explode('.',$temp['name']);
                        $num = count($name);
                        $suffix = strtolower($name[$num - 1]);
                        array_pop($name);
                        $temp['name'] = implode('.',$name).'.'.$suffix;
                    }

                    $item[] = new UploadedFile($temp['tmp_name'], $temp['name'], $temp['type'], $temp['error']);
                }

                $array[$key] = $item;
            } else {
                if ($file instanceof File) {
                    $array[$key] = $file;
                } else {
                    if ($file['error'] > 0) {
                        if ($key == $name) {
                            $this->throwUploadFileError($file['error']);
                        } else {
                            continue;
                        }
                    }

                    $name = explode('.',$file['name']);
                    $num = count($name);
                    $suffix = strtolower($name[$num - 1]);
                    array_pop($name);
                    $file['name'] = implode('.',$name).'.'.$suffix;

                    $array[$key] = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['error']);
                }
            }
        }
        return $array;
    }
}
